<template>
  <div class="container">
    <Breadcrumb :items="['系统管理', '用户管理']"/>
    <el-card class="general-card" title="用户管理">
      <el-form :model="searchModel" label-align="left">
        <el-row :gutter="20">
          <el-col class="search-tag-col" :span="6">
            <el-form-item ptop="username" label="用户名">
              <el-input v-model="searchModel.username" placeholder="输入用户名" clearable maxlength="10"
                        show-word-limit/>
            </el-form-item>
          </el-col>
          <el-col class="search-tag-col" :span="6">
            <el-form-item prop="nickName" label="昵称">
              <el-input v-model="searchModel.nickName" placeholder="输入昵称" clearable maxlength="10"
                        show-word-limit/>
            </el-form-item>
          </el-col>
          <el-col :span="6">
            <el-space :size="9">
              <el-button type="primary" @click="search">
                <template #icon>
                  <el-icon>
                    <Search/>
                  </el-icon>
                </template>
                查询
              </el-button>
              <el-button @click="reset">
                <template #icon>
                  <el-icon>
                    <Refresh/>
                  </el-icon>
                </template>
                重置
              </el-button>
            </el-space>
          </el-col>
        </el-row>
      </el-form>
      <el-divider style="margin-top: 0"/>
      <el-row style="margin-bottom: 16px">
        <el-col :span="12">
          <el-space>
            <el-button type="primary" @click="addItem">
              <template #icon>
                <el-icon>
                  <Plus/>
                </el-icon>
              </template>
              新增
            </el-button>
          </el-space>
        </el-col>
      </el-row>
      <el-table
          row-key="userId"
          :loading="loading"
          :data="renderData"
          stripe
          :size="size"
          table-layout="auto"
      >
        <el-table-column prop="userId" label="用户编号"></el-table-column>
        <el-table-column prop="username" label="用户名"></el-table-column>
        <el-table-column prop="nickName" label="昵称"></el-table-column>
        <el-table-column prop="gender" label="性别">
          <template #default="{row}">
            {{ $t(`sysUser.gender.${row.gender}`) }}
          </template>
        </el-table-column>
        <el-table-column prop="phone" label="手机号"></el-table-column>
        <el-table-column prop="email" label="邮箱"></el-table-column>
        <el-table-column prop="registrationDate" label="注册时间"></el-table-column>
        <el-table-column label="操作">
          <template #default="{row}">
            <el-button v-permission="['admin']" type="primary" text size="small" @click="infoItem(row.userId)">
              详情
            </el-button>
            <el-button v-permission="['admin']" type="primary" text size="small" @click="editItem(row.userId)">
              <el-icon>
                <Edit/>
              </el-icon>
              修改
            </el-button>
            <el-button v-if="row.status === '1'" v-permission="['admin']" size="small" type="success" text
                       @click="statusItem(row.userId)">
              启用
            </el-button>
            <el-button v-if="row.status === '0'" v-permission="['admin']" size="small" type="danger" text
                       @click="statusItem(row.userId)">
              停用
            </el-button>
            <el-popconfirm v-if="row.userId !== 1" v-permission="['admin']" content="你确定要删除吗?"
                           @ok="delItem(row.userId)">
              <el-button type="danger" text size="small">
                <el-icon>
                  <Delete/>
                </el-icon>
                删除
              </el-button>
            </el-popconfirm>
          </template>
        </el-table-column>
      </el-table>
    </el-card>

    <!--  新增修改弹窗  -->
    <el-dialog ref="modalFormRef"
               v-model="formModelSetting.visible"
               :loading="formModelSetting.onLoading"
               :title="formModelSetting.title"
               @close="modelCancel">
      <el-form ref="formRef" :model="formData" label-width="auto" label-position="right">
        <el-form-item prop="username" label="用户名" :rules="[{required:true, message: '用户名不能为空'}]">
          <el-input v-model="formData.username" placeholder="请输入用户名" clearable maxlength="10" show-word-limit/>
        </el-form-item>
        <el-form-item v-if="formData.userId === ''" prop="newPassword" label="密码"
                      :rules="[{required:true, message: '密码不能为空'}]">
          <el-input v-model="formData.newPassword" type="password" placeholder="请输入密码" clearable maxlength="16"
                    show-word-limit/>
        </el-form-item>
        <el-form-item prop="nickName" label="昵称" :rules="[{required:true, message: '状态不能为空'}]">
          <el-input v-model="formData.nickName" placeholder="请输入昵称" clearable maxlength="10" show-word-limit/>
        </el-form-item>
        <el-form-item prop="roleIds" label="角色" :rules="[{required:true, message: '角色不能为空'}]">
          <el-select v-model="formData.roleIds"
                     :options="dataOptions.roleList"
                     :props="{value: 'roleId', label: 'roleName'}"
                     placeholder="请选择角色"
                     multiple
                     :max-tag-count="3"
                     allow-search/>
        </el-form-item>
        <el-form-item field="phone" label="手机号码">
          <el-input v-model="formData.phone" placeholder="请输入手机号码" clearable maxlength="11" show-word-limit/>
        </el-form-item>
        <el-form-item field="email" label="邮箱">
          <el-input v-model="formData.email" placeholder="请输入邮箱" clearable maxlength="20" show-word-limit/>
        </el-form-item>

      </el-form>

      <template #footer>
        <div>
          <el-button @click="modelCancel">取消</el-button>
          <el-button type="primary" @click="modelOkBut">
            {{ formModelSetting.okText }}
          </el-button>
        </div>
      </template>
    </el-dialog>

    <!--  详情弹窗表单  -->
    <el-dialog ref="modalDetailRef"
               v-model="formModelDetailSetting.visible"
               @close="modelDetailOkBut">
      <el-descriptions :size="size" :column="2">
        <el-descriptions-item label="用户名">{{ formDataDetail.username }}</el-descriptions-item>
        <el-descriptions-item label="昵称">{{ formDataDetail.nickName }}</el-descriptions-item>
        <el-descriptions-item label="手机">{{ formDataDetail.phone }}</el-descriptions-item>
        <el-descriptions-item label="邮箱">{{ formDataDetail.email }}</el-descriptions-item>
        <el-descriptions-item label="性别">{{ $t(`sysUser.gender.${formDataDetail.gender}`) }}</el-descriptions-item>
        <el-descriptions-item label="注册时间">{{ formDataDetail.registrationDate }}</el-descriptions-item>
      </el-descriptions>
    </el-dialog>
  </div>
</template>

<script lang="ts" setup>
import {computed, reactive, ref} from 'vue';
import useLoading from '@/hooks/loading';
import {Pagination} from '@/types/global';
import {
  addUser,
  addUserParams,
  editUser,
  editUserParams,
  removeBatch,
  updateStatue,
  userInfo,
  userList,
  UserParams
} from '@/api/system/user';
import {selectRoleList} from '@/api/system/role';
import {ElMessage} from 'element-plus';

type SizeProps = 'mini' | 'small' | 'medium' | 'large';
const size = ref<SizeProps>('medium');
const {loading, setLoading} = useLoading(true);

const dataOptions = reactive({
  roleList: []
});
const getRoles = async () => {
  const {code, data}: any = await selectRoleList('');
  if (code === 200 && data) {
    dataOptions.roleList = data as any;
  }
}

// 表格列
const columns = computed<any[]>(() => [
  {
    title: '用户编号',
    dataIndex: 'userId',
    align: 'center',
  },
  {
    title: '用户名',
    dataIndex: 'username',
    align: 'center',
  },
  {
    title: '昵称',
    dataIndex: 'nickName',
    align: 'center',
  },
  {
    title: '性别',
    dataIndex: 'gender',
    slotName: 'gender',
    align: 'center',
  },
  {
    title: '手机号',
    dataIndex: 'phone',
    align: 'center',
  },
  {
    title: '邮箱',
    dataIndex: 'email',
    align: 'center',
  },
  {
    title: '注册时间',
    dataIndex: 'registrationDate',
    align: 'center',
  },
  {
    title: '操作',
    dataIndex: 'operations',
    slotName: 'operations',
    align: 'center',
  },
]);
const renderData = ref<UserParams[]>([]);

// 搜索数据模型
const searchFormModel = () => {
  return {
    userId: '',
    username: '',
    nickName: '',
    phone: '',
    email: '',
    gender: '',
    registrationDate: '',
  };
};
const searchModel = ref(searchFormModel());

// 查询用户列表
const getDataList = async (
    params: UserParams = {
      userId: 0,
      username: "",
      nickName: "",
      email: "",
      phone: "",
      registrationDate: ""
    }
) => {
  setLoading(true);
  try {
    const {data} = await userList(params);
    renderData.value = data.rows;
    pagination.total = data.total;
  } catch (err) {
    console.log(err);
  } finally {
    setLoading(false);
  }
};
getDataList();

// 搜索
const search = () => {
  getDataList({
    ...pagination,
    ...searchModel.value,
  } as unknown as UserParams);
}
// 搜索表单重置
const reset = () => {
  searchModel.value = searchFormModel();
};

// 分页
const basePagination: Pagination = {
  pageNumber: 1,
  pageSize: 10,
};
const pagination = reactive({
  ...basePagination,
});
const pageChange = async (current: number) => {
  pagination.pageNumber = current;
  await getDataList({
    ...pagination,
    ...searchModel.value,
  } as unknown as UserParams);
}
const pageSizeChange = async (pageSize: number) => {
  pagination.pageSize = pageSize;
  await getDataList({
    ...pagination,
    ...searchModel.value,
  } as unknown as UserParams);
};

// 删除按钮
const delItem = async (userId: number) => {
  const {code}: any = await removeBatch([userId]);
  if (code === 200) {
    ElMessage.success({
      message: `删除成功`,
      duration: 2 * 1000,
    });
    await getDataList();
  }
};

// 新增或修改表单
const formData = reactive({
  userId: '',
  username: '',
  newPassword: '',
  nickName: '',
  phone: '',
  email: '',
  gender: '',
  roleIds: []
});
const formRef = ref();
// 重置表单模型
const resetFormData = async () => {
  formData.userId = '';
  formData.username = '';
  formData.newPassword = '';
  formData.nickName = '';
  formData.phone = '';
  formData.email = '';
  formData.gender = '';
  formData.roleIds = [];
  if (formRef.value) {
    formRef.value.clearValidate();
  }
}


// 新增或修改对话框是否展示
const formModelSetting = reactive({
  visible: false,
  onLoading: false,
  title: "",
  okText: "",
  cancelText: "",
});
const modalFormRef = ref();

// 新增按钮
const addItem = async () => {
  await resetFormData();
  await getRoles();
  formModelSetting.title = '新增用户';
  formModelSetting.okText = '新增';
  formModelSetting.visible = true;
}

// 修改按钮
const editItem = async (userId: number) => {
  await resetFormData();
  await getRoles();
  // 查询
  const {code, msg, data}: any = await userInfo(userId);
  // 赋值
  if (code === 200 && data) {
    formData.userId = data.userId;
    formData.username = data.username;
    formData.nickName = data.nickName;
    formData.newPassword = data.password;
    formData.email = data.email;
    formData.phone = data.phone;
    formData.gender = data.gender;
    formData.roleIds = data.roleIds;
    // 打开弹窗
    formModelSetting.title = '修改用户';
    formModelSetting.okText = '修改';
    formModelSetting.visible = true;
  } else {
    ElMessage.warning({
      message: msg,
      duration: 2 * 1000,
    });
  }
}

// 表单确实之前
const modelBeforeOk = async () => {
  let flag = true;
  // 提交表单
  await formRef.value.validate().then((res: any) => {
    if (res !== undefined) {
      flag = false;
      formModelSetting.visible = true;
      formModelSetting.onLoading = false;
    }
  });
  // 请求
  if (flag) {

  }
  return flag;
}

// 表单确定按钮
const modelOkBut = () => {
  formRef.value.validate(async (valid: any) => {
    if (valid) {
      if (formData.userId) {
        // 修改
        const params: editUserParams = {
          userId: formData.userId,
          username: formData.username,
          newPassword: formData.newPassword,
          nickName: formData.nickName,
          phone: formData.phone,
          email: formData.email,
          roleIds: formData.roleIds
        };
        const {code}: any = await editUser(params);
        if (code === 200) {
          ElMessage.success({
            message: `修改成功`,
            duration: 2 * 1000,
          });
          getDataList();
          modelCancel();
        }
      } else {
        const params: addUserParams = {
          username: formData.username,
          newPassword: formData.newPassword,
          nickName: formData.nickName,
          phone: formData.phone,
          email: formData.email,
          roleIds: formData.roleIds
        };
        const {code}: any = await addUser(params);
        if (code === 200) {
          ElMessage.success({
            message: `新增成功`,
            duration: 2 * 1000,
          });
          getDataList();
          modelCancel();
        }
      }
    }
  })
}

// 新增或修改弹窗取消按钮
const modelCancel = () => {
  formModelSetting.visible = false;
  resetFormData();
}

// 详情表单模型
const formDataDetail = reactive({
  userId: 0,
  username: '',
  email: '',
  nickName: '',
  phone: '',
  gender: '',
  registrationDate: '',
});
// 重置表单模型
const resetFormDataDetail = () => {
  formDataDetail.userId = 0;
  formDataDetail.username = '';
  formDataDetail.email = '';
  formDataDetail.nickName = '';
  formDataDetail.phone = '';
  formDataDetail.gender = '';
  formDataDetail.registrationDate = '';
}
const modalDetailRef = ref();

// 详情对话框是否展示
const formModelDetailSetting = reactive({
  visible: false,
  onLoading: false,
  title: "用户信息",
  okText: "",
  cancelText: "",
});

// 详情按钮
const infoItem = async (userId: number) => {
  // 查询
  const {code, msg, data}: any = await userInfo(userId);
  // 赋值
  if (code === 200 && data) {
    formDataDetail.userId = data.userId;
    formDataDetail.username = data.username;
    formDataDetail.nickName = data.nickName;
    formDataDetail.email = data.email;
    formDataDetail.phone = data.phone;
    formDataDetail.gender = data.gender;
    formDataDetail.registrationDate = data.registrationDate;
    // 打开弹窗
    formModelDetailSetting.visible = true;
    formModelDetailSetting.onLoading = false;
  } else {
    ElMessage.warning({
      message: msg,
      duration: 2 * 1000,
    });
  }
};

// 表单确定按钮
const modelDetailOkBut = async () => {
  // 关闭弹窗
  formModelDetailSetting.visible = false;
  formModelDetailSetting.onLoading = false;
  // 重置表单
  resetFormDataDetail();
};

// 修改状态
const statusItem = async (userId: number) => {
  const {code, msg}: any = await updateStatue(userId);
  if (code === 200) {
    ElMessage.success({
      message: '操作成功',
      duration: 2 * 1000,
    });
    await getDataList();
  } else {
    ElMessage.warning({
      message: msg,
      duration: 2 * 1000,
    });
  }
}

</script>

<style lang="less" scoped>
:deep(.cell) {
  display: flex;
  justify-content: center;
}
</style>
